use super::into_iter::IntoIter;
use super::iter::Iter;
use super::iter_mut::IterMut;

#[derive(Debug, Clone)]
pub struct Queue<T> {
    pub cap: usize,
    pub data: Vec<T>,
}

impl<T> Queue<T> {
    pub fn new(size: usize) -> Queue<T> {
        Queue {
            cap: size,
            data: Vec::with_capacity(size),
        }
    }

    pub fn len(&self) -> usize {
        self.data.len()
    }
    pub fn is_empty(&self) -> bool {
        0 == Self::len(&self)
    }

    pub fn is_full(&self) -> bool {
        self.len() == self.cap
    }

    pub fn clear(&mut self) {
        self.data = Vec::with_capacity(self.cap)
    }

    pub fn enqueue(&mut self, val: T) -> Result<(), String> {
        if self.len() == self.cap {
            return Err("No space available".to_string());
        }
        self.data.insert(0, val);
        Ok(())
    }

    pub fn dequeue(&mut self) -> Option<T> {
        if self.len() > 0 {
            self.data.pop()
        } else {
            None
        }
    }
    pub fn into_iter(self) -> IntoIter<T> {
        IntoIter::new(self)
    }

    pub fn iter(&self) -> Iter<T> {
        let mut iterator = Iter { stack: Vec::new() };
        for item in self.data.iter() {
            iterator.stack.push(item);
        }
        iterator
    }

    pub fn iter_mut(&mut self) -> IterMut<T> {
        let mut iterator = IterMut { stack: Vec::new() };
        for item in self.data.iter_mut() {
            iterator.stack.push(item);
        }
        iterator
    }
}
